package com.cn.por.auto.factory;

import com.cn.por.auto.dto.DataModel;
import com.cn.por.auto.dto.ModelParam;
import com.cn.por.auto.enums.ModelType;
import com.cn.por.util.freemarker.FreeMarkerUtil;
import freemarker.template.TemplateException;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 代码工厂类，通过传入不同的frameworkType,生成不同的基础代码，用
 * 工厂模式就是在于方便用户只要输入类型就可以生成所需代码，不需要复杂
 * 的入参。
 *
 * 这个工厂类是生成打包后的代码
 */
public class CodeFactory {

    public CodeFactory(){}

    /**
     * 提供给用户使用的代码生成接口，通过传入不同的frameworkType,生成不同的基础代码,比如
     * 传入hsa，则生成基于hsa架构的前后端代码。
     * @param frameworkType
     * @param modelParam
     * @return
     */
    public Map<String,byte[]> generateCode(String frameworkType, ModelParam modelParam){
        Map<String,byte[]> resultByte = new HashMap<>();
        switch (frameworkType){
            case "hsa":
                this.generateMybatisPlus(modelParam,resultByte);
                this.generateElementUi(modelParam,resultByte);
                break;
            default:
                break;
        }
        return  resultByte;
    }

    /**
     * 生成mybatisPlus+springmvc后端基础代码,格式为字节数组
     * @param modelParam
     * @return
     */
    private Map<String,byte[]> generateMybatisPlus(ModelParam modelParam, Map<String,byte[]> resultByte){
        SpringMybatisPlusDataModelFactory factory = new SpringMybatisPlusDataModelFactory(modelParam);
        try {
            /**
             * 添加dto对象
             */
            DataModel dto = factory.getDataModel(ModelType.DTO);
            resultByte.put(dto.getZipDir(), FreeMarkerUtil.dataFormateByte(dto));
            /**
             * 添加do对象
             */
            DataModel DO = factory.getDataModel(ModelType.DO);
            resultByte.put(DO.getZipDir(), FreeMarkerUtil.dataFormateByte(DO));
            /**
             * 添加converter
             */
            DataModel converter = factory.getDataModel(ModelType.CONVERTER);
            resultByte.put(converter.getZipDir(), FreeMarkerUtil.dataFormateByte(converter));
            /**
             * 添加controller
             */
            DataModel controller = factory.getDataModel(ModelType.CONTROLLER);
            resultByte.put(controller.getZipDir(),FreeMarkerUtil.dataFormateByte(controller));
            /**
             * 添加service
             */
            DataModel service = factory.getDataModel(ModelType.SERVICE);
            resultByte.put(service.getZipDir(),FreeMarkerUtil.dataFormateByte(service));
            /**
             * 添加serviceImpl
             */
            DataModel serviceImpl = factory.getDataModel(ModelType.SERVICE_IMPL);
            resultByte.put(serviceImpl.getZipDir(),FreeMarkerUtil.dataFormateByte(serviceImpl));
            /**
             * 添加bo
             */
            DataModel bo = factory.getDataModel(ModelType.BO);
            resultByte.put(bo.getZipDir(),FreeMarkerUtil.dataFormateByte(bo));
            /**
             * 添加boImpl
             */
            DataModel boImpl = factory.getDataModel(ModelType.BO_IMPL);
            resultByte.put(boImpl.getZipDir(),FreeMarkerUtil.dataFormateByte(boImpl));
            /**
             * 添加DAO
             */
            DataModel dao = factory.getDataModel(ModelType.DAO);
            resultByte.put(dao.getZipDir(),FreeMarkerUtil.dataFormateByte(dao));
            /**
             * 添加mapper
             */
            DataModel mapper = factory.getDataModel(ModelType.MAPPER);
            resultByte.put(mapper.getZipDir(),FreeMarkerUtil.dataFormateByte(mapper));
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }
        return  resultByte;
    }

    /**
     * 生成element-ui框架的基本代码
     * @param modelParam
     * @param resultByte
     * @return
     */
    private Map<String,byte[]> generateElementUi(ModelParam modelParam, Map<String,byte[]> resultByte){
        ElementUiFactory elementUiFactory = new ElementUiFactory(modelParam);

        try {
            DataModel js = elementUiFactory.getDataModel(ModelType.JS);
            resultByte.put(js.getZipDir(),FreeMarkerUtil.dataFormateByte(js));

            DataModel index = elementUiFactory.getDataModel(ModelType.INDEX);
            resultByte.put(index.getZipDir(),FreeMarkerUtil.dataFormateByte(index));

            DataModel add = elementUiFactory.getDataModel(ModelType.ADD);
            resultByte.put(add.getZipDir(),FreeMarkerUtil.dataFormateByte(add));

            DataModel modify = elementUiFactory.getDataModel(ModelType.MODIFY);
            resultByte.put(modify.getZipDir(),FreeMarkerUtil.dataFormateByte(modify));

            DataModel preview = elementUiFactory.getDataModel(ModelType.PREVIEW);
            resultByte.put(preview.getZipDir(),FreeMarkerUtil.dataFormateByte(preview));
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        }
        return resultByte;
    }


}
